package com.uvt.agenda.database;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import com.uvt.agenda.Event;
import com.uvt.agenda.adapter.EventAdapter;

import org.joda.time.DateTime;

import java.util.ArrayList;

/**
 * Created by Cristian Holdunu on 31/01/14.
 * 20:44
 */
public class DatabaseManager extends SQLiteOpenHelper {

    private static String DB_PATH;

    private static final String DB_NAME = "android_agenda.db";

    /**
     * Events table fields
     */
    private static final String EVENTS_TABLE = "events";
    private static final String EVENT_ID = "id";
    private static final String EVENT_NAME = "name";
    private static final String EVENT_DESCRIPTION = "description";
    private static final String EVENT_FROM = "start_time";
    private static final String EVENT_TO = "end_time";
    private static final String EVENT_REMINDER = "event_reminder";

    /**
     * Queries for the events table
     */
    private static final String CREATE_DATABASE = "create table "
            + EVENTS_TABLE + "("
            + EVENT_ID + " integer primary key autoincrement, "
            + EVENT_NAME + " text not null, "
            + EVENT_DESCRIPTION + " text, "
            + EVENT_FROM + " INTEGER NOT NULL, "
            + EVENT_TO + " INTEGER "
            + EVENT_REMINDER + " INTEGER "
            + ");";

    /**
     * Get all events
     */
    private static final String SELECT_ALL_EVENTS =
            "SELECT * FROM " + EVENTS_TABLE + ";";

    /**
     * Save new event to database
     */
    private static final String INSERT_NEW_EVENT =
            "INSERT INTO "
            + EVENTS_TABLE + " ("
            + EVENT_NAME + ", "
            + EVENT_DESCRIPTION + ", "
            + EVENT_FROM + ", "
            + EVENT_TO + ", "
            + EVENT_REMINDER + ") values ( ?, ?, ?, ?, ?,);";

    /**
     * Get the events between 2 timestamps
     */
    private static final String SELECT_IN_INTERVAL =
            "SELECT * FROM " + EVENTS_TABLE + " where "
            + EVENT_FROM + " > ? and "
            + EVENT_TO + " < ? ;";

    private SQLiteDatabase dataBase;
    private final Context context;

    public DatabaseManager(Context context) {
        super(context, DB_NAME, null, 1);
        this.context = context;
        DB_PATH = context.getDatabasePath(DB_NAME).toString() ;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_DATABASE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    public void openDataBase() throws SQLException {
        // Open the database
        dataBase = this.getWritableDatabase();
    }

    @Override
    public synchronized void close() {
        if (dataBase != null)
            dataBase.close();
        dataBase = null;
        super.close();
    }

    /**
     * Get all events from database
     */
    public ArrayList<Event> getAllEvents () {
        Cursor cursor;
        ArrayList<Event> resultEvents = new ArrayList<Event>();

        cursor = dataBase.rawQuery(SELECT_ALL_EVENTS, null);
        if (cursor !=null) {
            cursor.moveToFirst();
            while (!cursor.isAfterLast()) {
                resultEvents.add(EventAdapter.toEvent(cursor));
                cursor.moveToNext();
            }
        }
        return resultEvents;
    }

    /**
     * Get events for a specific month
     * @param referenceDate with the first day of the month
     *                      in which we want to get the events
     */
    public ArrayList<Event> getMonthEvents(DateTime referenceDate) {
        ArrayList<Event> resultEvents = new ArrayList<Event>();
        Cursor cursor;
        Long startTimestamp = referenceDate.getMillis();
        Long endTimestamp = referenceDate.plusMonths(1).getMillis();

        cursor = dataBase.rawQuery(SELECT_IN_INTERVAL, new String[] {startTimestamp + "", endTimestamp + ""});
        if (cursor !=null) {
            cursor.moveToFirst();
            while (!cursor.isAfterLast()) {
                resultEvents.add(EventAdapter.toEvent(cursor));
                cursor.moveToNext();
            }
        }
        return resultEvents;
    }

//    /**
//     * Convert database entry to Event (from cursor)
//     */
//    public Event cursorToEvent(Cursor cursor) {
//        Event event = new Event();
//        event.setID(cursor.getInt(0));
//        event.setName(cursor.getString(1));
//        event.setDescription(cursor.getString(2));
//        event.setStartDate( cursor.getLong(3));
//        event.setEndDate( cursor.getLong(4));
//        return event;
//    }

    /**
     * Insert new event into database
     * @param event
     */
    public void saveNewEvent(Event event) {
        if (dataBase == null || !dataBase.isOpen()) {
            dataBase = this.getWritableDatabase();
        }

        ContentValues eventValues = new ContentValues();
        eventValues.put(EVENT_NAME, event.getName());
        eventValues.put(EVENT_DESCRIPTION, event.getDescription());
        eventValues.put(EVENT_FROM, event.getStartDate());
        eventValues.put(EVENT_TO, event.getEndDate());

        dataBase.insert(EVENTS_TABLE, null, eventValues);
    }

    /**
     * Update event in database
     */
    public void updateEvent(Event event) {
        if (dataBase == null || !dataBase.isOpen()) {
            dataBase = this.getWritableDatabase();
        }

        ContentValues eventValues = new ContentValues();
        eventValues.put(EVENT_NAME, event.getName());
        eventValues.put(EVENT_DESCRIPTION, event.getDescription());
        eventValues.put(EVENT_FROM, event.getStartDate());
        eventValues.put(EVENT_TO, event.getEndDate());

        dataBase.update(EVENTS_TABLE,
                eventValues,
                EVENT_ID + " = ? ",new String [] {String.valueOf(event.getID())});
    }

    /**
     * Delete event from database
     */
    public void deleteEvent(Event event) {
        if (dataBase == null || !dataBase.isOpen()) {
            dataBase = this.getWritableDatabase();
        }
        dataBase.delete(EVENTS_TABLE,
                EVENT_ID + " = ? ",
                new String [] {String.valueOf(event.getID())});
    }

}
